package cn.ac.iie.unpack.file.main;

import cn.ac.iie.mqSender.DistriThread;
import cn.ac.iie.unpack.file.global.GlobalParas;
import cn.ac.iie.unpack.file.utils.FileUntarAndMoveThread;
import cn.ac.iie.unpack.file.utils.FileListGetThread;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.logging.Level;
import org.apache.commons.configuration2.ex.ConfigurationException;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

/**
 * Created by moli
 */
public class UnpackFileMain {
    
    public volatile static boolean Stop;
    public static Logger LOG = Logger.getLogger(UnpackFileMain.class);
    public static GlobalParas globalParas = null;

    public static void main(String[] args) throws ConfigurationException {
        GlobalParas.getIstance(GlobalParas.DEFAULT_CONFIGURATION);
        PropertyConfigurator.configure(ClassLoader.getSystemClassLoader().getResource(globalParas.LOG4_CONFIGURATION));

//        File inputFile=new File("C:\\Users\\gjw\\Desktop\\projects\\sfiles\\molua - 副本 (2).tar");
//        File outputDir=new File("C:\\Users\\gjw\\Desktop\\projects\\dfiles");
//        
//        if(!inputFile.exists()){
//            LOG.error(String.format("The file ==haha== does not exist."));
//        }
//        FileUntar fileUntar=new FileUntar();
//        try {
//            fileUntar.unTar(inputFile, outputDir);
//        } catch (ArchiveException ex) {
//            LOG.error(ExceptionUtils.getFullStackTrace(ex));
//        } catch (IOException ex) {
//            LOG.error(ExceptionUtils.getFullStackTrace(ex));
//        }
        File tarFile = new File(GlobalParas.SOURCE_DIR);
        if (!tarFile.exists()) {
            LOG.error(String.format("%s dir does not exists.", tarFile));
        }

        File untaredDir = new File(GlobalParas.PARSER_DESTINATION_DIR);
        if (!untaredDir.exists()) {
            untaredDir.mkdir();
        }
        
        
        
        final FutureTask<Integer> get_stop = new FutureTask<Integer>(new FileListGetThread());
        new Thread(get_stop).start();
        ExecutorService unpackPool = Executors.newFixedThreadPool(GlobalParas.UNPACK_THREAD_NUM);
        FileUntarAndMoveThread fileUntarAndMoveThread = new FileUntarAndMoveThread(untaredDir);
        final List<Future<Integer>> untarStop=new ArrayList();
        for (int i = 0; i < GlobalParas.UNPACK_THREAD_NUM; i++) {
            untarStop.add(unpackPool.submit(fileUntarAndMoveThread));
        }
        final List<Future> sendMqStop=DistriThread.getDistriThread();
        final FutureTask<Integer> distriStop = new FutureTask<Integer>(new DistriThread());
        new Thread(distriStop).start();
        for (int i = 0; i < GlobalParas.UNPACK_THREAD_NUM; i++) {
            untarStop.add(unpackPool.submit(fileUntarAndMoveThread));
        }
        
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                Stop=true;
                try {
                    get_stop.get();
                    FileListGetThread.Stop=true;
                    LOG.info("FileListGetThread.Stop");
                    for(Future f:untarStop){
                        f.get();
                    }
                    LOG.info("untarStop");
                    FileUntarAndMoveThread.Stop=true;
                    distriStop.get();
                    LOG.info("FileUntarAndMoveThread.Stop");
                    DistriThread.Stop=true;
                    for(Future f:sendMqStop){
                        f.get();
                    }
                    LOG.info("FileListGetThread.Stop");
                    DistriThread.threadService.shutdown();
                } catch (InterruptedException ex) {
                     LOG.error(ExceptionUtils.getFullStackTrace(ex));
                } catch (ExecutionException ex) {
                     LOG.error(ExceptionUtils.getFullStackTrace(ex));
                }
                
            }
        });
        LOG.info("start successful");
    }
}
